﻿#include "GraphMarkProvider.h"

// App
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"

// Global data
#include "FITK_Kernel/FITKCore/FITKDataRepo.h"

// Data
#include "FITK_Interface/FITKInterfaceGeometry/FITKGeoCommandList.h"
#include "FITK_Interface/FITKInterfaceGeometry/FITKAbsGeoCommand.h"
#include "FITK_Component/FITKAbaqusData/FITKDataCase.h"
#include "FITK_Component/FITKAbaqusData/FITKAbaqusPart.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsSEAModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsDiscModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKSEAAbstractJunction.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsFEModel.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsLoadManager.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsAbstractLoad.h"

// Render VTK
#include "FITK_Component/FITKRenderWindowVTK/FITKGraph3DWindowVTK.h"
#include "FITK_Component/FITKRenderWindowVTK/FITKGraphRender.h"

// Graph
#include "FITK_Component/FITKAcousticsVTKGraphAdaptor/FITKAcousticsVTKGraphObject3D.h"
#include "FITK_Component/FITKAcousticsVTKGraphAdaptor/FITKAcousticsVTKGraphObjectScalarBars.h"

// View
#include "FITK_Component/FITKAcousticsVTKGraphAdaptor/FITKAcousticsVTKViewAdaptorBase.h"

namespace GraphData
{
    int GraphMarkProvider::m_graphToolId = 0;

    GraphMarkProvider::GraphMarkProvider(Comp::FITKGraph3DWindowVTK* graphWidget)
        : GraphProviderBase(graphWidget)
    {

    }

    GraphMarkProvider::~GraphMarkProvider()
    {
        // 析构三维可视化对象。
        deleteObjsHash(m_SEAFreeEdgesObjHash);
        deleteObjsHash(m_SEAJuncPointObjHash);

#if SUBSYSTEM_MERGE
        deleteObjsHash(m_SEAJuncLinesObjHash);
        deleteObjsHash(m_SEAJuncAreasObjHash);
#else
        deleteObjsHash(m_SEAJuncLineObjHash);
        deleteObjsHash(m_SEAJuncAreaObjHash);
#endif    

        deleteObjsHash(m_loadPointForceObjHash);
        deleteObjsHash(m_loadPowerObjHash);
        deleteObjsHash(m_loadConstraintObjHash);
        deleteObjsHash(m_importNoiseHVACHash);
        deleteObjsHash(m_loadMonopoleObjHash);

        if (m_scalarBarObj)
        {
            delete m_scalarBarObj;
            m_scalarBarObj = nullptr;
        }
    }

    QString GraphMarkProvider::getClassName()
    {
        return "GraphMarkProvider";
    }

    bool GraphMarkProvider::updateObjById(int dataId, bool forceUpdate)
    {
        Exchange::FITKAcousticsVTKGraphObject3D* obj = getCurrentGraphObjByDataId(dataId);
        if (!obj)
        {
            return false;
        }

        obj->update(forceUpdate);

        return true;
    }

    QList<Exchange::FITKAcousticsVTKGraphObject3D*> GraphMarkProvider::getCurrentGraphObjs()
    {
        // 当前所有可视化对象数据。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs;

        // SEA自由边可视化对象。
        objs << m_SEAFreeEdgesObjHash.values();   

        // SEA连接点可视化对象。
        objs << m_SEAJuncPointObjHash.values();

#if SUBSYSTEM_MERGE
        // SEA连接线可视化对象。
        objs << m_SEAJuncLinesObjHash.values();

        // SEA连接面可视化对象。
        objs << m_SEAJuncAreasObjHash.values();
#else
        // SEA连接线可视化对象。
        objs << m_SEAJuncLineObjHash.values();

        // SEA连接面可视化对象。
        objs << m_SEAJuncAreaObjHash.values();
#endif

        // 力矩可视化对象。
        objs << m_loadPointForceObjHash.values();

        // 功率可视化对象。
        objs << m_loadPowerObjHash.values();

        // 约束可视化对象。
        objs << m_loadConstraintObjHash.values();

        //噪声载荷
        objs << m_importNoiseHVACHash.values();

        // 单极子载荷
        objs << m_loadMonopoleObjHash.values();

        return objs;
    }

    QList<Exchange::FITKAcousticsVTKGraphObject3D*> GraphMarkProvider::getCurrentCameraSenGraphObjs()
    {
        // 当前所有相机敏感可视化对象数据。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs;

        // 功率可视化对象。
        objs << m_loadPowerObjHash.values();

        // 约束可视化对象。
        objs << m_loadConstraintObjHash.values();

        // 噪声载荷
        objs << m_importNoiseHVACHash.values();

        // 单极子载荷
        objs << m_loadMonopoleObjHash.values();

        return objs;
    }

    Exchange::FITKAcousticsVTKGraphObject3D* GraphMarkProvider::getJunctionGraphObject(int dataObjId, bool forceUpdate)
    {
        // 连接关系可视化对象。
        Exchange::FITKAcousticsVTKGraphObject3D* obj{ nullptr };

        // 检查数据ID。
        Acoustics::FITKAbstractJunction* junction = FITKDATAREPO->getTDataByID<Acoustics::FITKAbstractJunction>(dataObjId);
        if (!junction){
            return obj;
        }

        Acoustics::FITKAbstractJunction::JunctionType juncType = junction->getJunctiontType();

        switch (juncType){
        case Acoustics::FITKAbstractJunction::JunctionType::SEAPointJunction:{
            // SEA连接点。
            obj = getGraphObject("SEAJunctionPoints", m_SEAJuncPointObjHash, m_discModel);
            break;
        }
        case Acoustics::FITKAbstractJunction::JunctionType::SEALineJunction:{
            // SEA连接线。
            obj = getGraphObject("SEAJunctionLines", m_SEAJuncLinesObjHash, m_discModel);
            break;
        }
        case Acoustics::FITKAbstractJunction::JunctionType::SEAAreaJunction:{
            // SEA连接区域。
            obj = getGraphObject("SEAJunctionAreas", m_SEAJuncAreasObjHash, m_discModel);
            break;
        }
        case Acoustics::FITKAbstractJunction::JunctionType::HybridPointJunction:{
            //混合点连接。
            obj = getGraphObject("HybridJunctionPoint", m_HybridJuncPointObjHash, junction);
            break;
        }
        case Acoustics::FITKAbstractJunction::JunctionType::HybridLineJunction:{
            //混合线连接。
            obj = getGraphObject("HybridJunctionLines", m_HybridJuncLinesObjHash, m_discModel);
            break;
        }
        case Acoustics::FITKAbstractJunction::JunctionType::HybridAreaJunction:{
            //混合面连接。
            obj = getGraphObject("HybridJunctionAreas", m_HybridJuncAreasObjHash, m_discModel);
            break;
        }
        case Acoustics::FITKAbstractJunction::JunctionType::FEPointJunction:{
            //FE点连接。
            obj = getGraphObject("FEJunctionPoint", m_FEJuncPointObjHash, junction);
            break;
        }
        case Acoustics::FITKAbstractJunction::JunctionType::FELineJunction:{
            //FE线连接。
            obj = getGraphObject("FEJunctionLines", m_FEJuncLinesObjHash, m_discModel);
            break;
        }
        case Acoustics::FITKAbstractJunction::JunctionType::FEAreaJunction:{
            //FE面连接。
            obj = getGraphObject("FEJunctionAreas", m_FEJuncAreasObjHash, m_discModel);
            break;
        }
        }

        // 局部刷新数据(点连接不会刷新局部数据，仅限复合数据)。
        if (obj){
            obj->updateById(dataObjId, forceUpdate);
        }

        return obj;
    }

    QList<Exchange::FITKAcousticsVTKGraphObject3D*> GraphMarkProvider::getAllJunctionGraphObjects(bool autoCreate)
    {
        // 获取全部连接关系可视化对象。
        return getJunctionGraphObjectsByType(Acoustics::FITKAbstractJunction::JunctionType::SEAPointJunction, autoCreate) +
            getJunctionGraphObjectsByType(Acoustics::FITKAbstractJunction::JunctionType::SEALineJunction, autoCreate) +
            getJunctionGraphObjectsByType(Acoustics::FITKAbstractJunction::JunctionType::SEAAreaJunction, autoCreate) +
            getJunctionGraphObjectsByType(Acoustics::FITKAbstractJunction::JunctionType::HybridPointJunction, autoCreate) +
            getJunctionGraphObjectsByType(Acoustics::FITKAbstractJunction::JunctionType::HybridLineJunction, autoCreate) +
            getJunctionGraphObjectsByType(Acoustics::FITKAbstractJunction::JunctionType::HybridAreaJunction, autoCreate) +
            getJunctionGraphObjectsByType(Acoustics::FITKAbstractJunction::JunctionType::FEPointJunction, autoCreate) +
            getJunctionGraphObjectsByType(Acoustics::FITKAbstractJunction::JunctionType::FELineJunction, autoCreate) +
            getJunctionGraphObjectsByType(Acoustics::FITKAbstractJunction::JunctionType::FEAreaJunction, autoCreate);
    }

    QList<Exchange::FITKAcousticsVTKGraphObject3D*> GraphMarkProvider::getJunctionGraphObjectsByType(int junctionTypeEnum, bool update)
    {
        // 连接关系可视化对象列表。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs;
        if (m_juncMgr == nullptr)return objs;
        int nJunc = m_juncMgr->getDataCount();

        //数据刷新局部函数
        auto updateMergedObj = [=](Exchange::FITKAcousticsVTKGraphObject3D* obj){
            if (obj == nullptr) {
                return;
            }

            for (int i = 0; i < nJunc; i++){
                Acoustics::FITKAbstractJunction* junc = m_juncMgr->getDataByIndex(i);
                if (junc == nullptr)continue;

                // 获取SEA连接关系类型。
                Acoustics::FITKAbstractJunction::JunctionType sjType = junc->getJunctiontType();
                if (sjType != junctionTypeEnum)continue;

                // 刷新数据。
                obj->updateById(junc->getDataObjectID());
            }
        };

        switch (junctionTypeEnum){
        case Acoustics::FITKAbstractJunction::JunctionType::SEAPointJunction:{
            // 实例化SEA连接线可视化对象。
            Exchange::FITKAcousticsVTKGraphObject3D* obj = getGraphObjectByKey("SEAJunctionPoints", m_SEAJuncPointObjHash,
                m_discModel, m_discModel->getDataObjectID());
            if (obj == nullptr)break;

            objs.push_back(obj);

            if (update) {
                updateMergedObj(obj);
            }
            break;
        }
        case Acoustics::FITKAbstractJunction::JunctionType::SEALineJunction:{
            // 实例化SEA连接线可视化对象。
            Exchange::FITKAcousticsVTKGraphObject3D* obj = getGraphObjectByKey("SEAJunctionLines", m_SEAJuncLinesObjHash,
                m_discModel, m_discModel->getDataObjectID());
            if (obj == nullptr)break;

            objs.push_back(obj);

            if (update){
                updateMergedObj(obj);
            }
            break;
        }
        case Acoustics::FITKAbstractJunction::JunctionType::SEAAreaJunction:{
            // 实例化SEA连接区域可视化对象。
            Exchange::FITKAcousticsVTKGraphObject3D* obj = getGraphObjectByKey("SEAJunctionAreas", m_SEAJuncAreasObjHash,
                m_discModel, m_discModel->getDataObjectID());
            if (obj == nullptr)break;

            objs.push_back(obj);

            if (update){
                updateMergedObj(obj);
            }
            break;
        }
        case Acoustics::FITKAbstractJunction::JunctionType::HybridPointJunction: {
            // 混合点连接
            for (int i = 0; i < nJunc; i++) {
                Acoustics::FITKAbstractJunction* junction = m_juncMgr->getDataByIndex(i);
                if (junction == nullptr)continue;
                if (junction->getJunctiontType() != junctionTypeEnum)continue;

                Exchange::FITKAcousticsVTKGraphObject3D* obj = getGraphObject("HybridJunctionPoint", m_HybridJuncPointObjHash, junction);
                objs.push_back(obj);

                if (update) {
                    updateMergedObj(obj);
                }
            }
            break;
        }
        case Acoustics::FITKAbstractJunction::JunctionType::HybridLineJunction: {
            // 混合线连接
            Exchange::FITKAcousticsVTKGraphObject3D* obj = getGraphObjectByKey("HybridJunctionLines", m_HybridJuncLinesObjHash,
                m_discModel, m_discModel->getDataObjectID());
            if (obj == nullptr)break;

            objs.push_back(obj);

            if (update) {
                updateMergedObj(obj);
            }
            break;
        }
        case Acoustics::FITKAbstractJunction::JunctionType::HybridAreaJunction: {
            // 混合面连接
            Exchange::FITKAcousticsVTKGraphObject3D* obj = getGraphObjectByKey("HybridJunctionAreas", m_HybridJuncAreasObjHash,
                m_discModel, m_discModel->getDataObjectID());
            if (obj == nullptr)break;

            objs.push_back(obj);

            if (update) {
                updateMergedObj(obj);
            }
            break;
        }
        case Acoustics::FITKAbstractJunction::JunctionType::FEPointJunction: {
            // FE点连接
            for (int i = 0; i < nJunc; i++) {
                Acoustics::FITKAbstractJunction* junction = m_juncMgr->getDataByIndex(i);
                if (junction == nullptr)continue;
                if (junction->getJunctiontType() != junctionTypeEnum)continue;

                Exchange::FITKAcousticsVTKGraphObject3D* obj = getGraphObject("FEJunctionPoint", m_FEJuncPointObjHash, junction);
                objs.push_back(obj);

                if (update) {
                    updateMergedObj(obj);
                }
            }
            break;
        }
        case Acoustics::FITKAbstractJunction::JunctionType::FELineJunction: {
            // FE线连接
            Exchange::FITKAcousticsVTKGraphObject3D* obj = getGraphObjectByKey("FEJunctionLines", m_FEJuncLinesObjHash,
                m_discModel, m_discModel->getDataObjectID());
            if (obj == nullptr)break;

            objs.push_back(obj);

            if (update) {
                updateMergedObj(obj);
            }
            break;
        }
        case Acoustics::FITKAbstractJunction::JunctionType::FEAreaJunction: {
            // FE面连接
            Exchange::FITKAcousticsVTKGraphObject3D* obj = getGraphObjectByKey("FEJunctionAreas", m_FEJuncAreasObjHash,
                m_discModel, m_discModel->getDataObjectID());
            if (obj == nullptr)break;

            objs.push_back(obj);

            if (update) {
                updateMergedObj(obj);
            }
            break;
        }
        }
        return objs;
    }

    Exchange::FITKAcousticsVTKGraphObject3D* GraphMarkProvider::getSEAFreeEdgesGraphObject(bool autoCreate)
    {
        // SEA模型自由边可视化对象。
        Exchange::FITKAcousticsVTKGraphObject3D* obj{ nullptr };

        if (!m_seaModel)
        {
            return obj;
        }

        if (autoCreate)
        {
            obj = getGraphObject("SEAFreeEdges", m_SEAFreeEdgesObjHash, m_seaModel);
        }
        else
        {
            int modelId = m_seaModel->getDataObjectID();
            if (m_SEAFreeEdgesObjHash.contains(modelId))
            {
                obj = m_SEAFreeEdgesObjHash[modelId];
            }
        }
        
        return obj;
    }

    Exchange::FITKAcousticsVTKGraphObject3D* GraphMarkProvider::getLoadGraphObject(int dataObjId)
    {
        // 载荷可视化对象。
        Exchange::FITKAcousticsVTKGraphObject3D* obj{ nullptr };

        // 检查数据ID。
        Acoustics::FITKAcousticsAbstractLoad* abLoad = FITKDATAREPO->getTDataByID<Acoustics::FITKAcousticsAbstractLoad>(dataObjId);
        if (!abLoad){
            return obj;
        }

        Acoustics::FITKAcousticsAbstractLoad::AcousticsLoadType cType = abLoad->getAcousticsLoadType();

        switch (cType){
        case Acoustics::FITKAcousticsAbstractLoad::ImportNoiseHVAC:
            obj = getGraphObject("LoadImport", m_importNoiseHVACHash, abLoad);
            break;
        case Acoustics::FITKAcousticsAbstractLoad::ConstraintSEABeam:
            obj = getGraphObject("LoadConstraintSEABeam", m_loadConstraintObjHash, abLoad);
            break;
        case Acoustics::FITKAcousticsAbstractLoad::ConstraintSEAShell:
            obj = getGraphObject("LoadConstraintSEAShell", m_loadConstraintObjHash, abLoad);
            break;
        case Acoustics::FITKAcousticsAbstractLoad::ConstraintSEAAcoustic:
            obj = getGraphObject("LoadConstraintSEAAcoustic", m_loadConstraintObjHash, abLoad);
            break;
        case Acoustics::FITKAcousticsAbstractLoad::ConstraintFESubsys:
            obj = getGraphObject("LoadConstraintFESubsys", m_loadConstraintObjHash, abLoad);
            break;
        case Acoustics::FITKAcousticsAbstractLoad::PowerSEABeam:
            obj = getGraphObject("LoadPowerSEABeam", m_loadPowerObjHash, abLoad);
            break;
        case Acoustics::FITKAcousticsAbstractLoad::PowerSEAShell:
            obj = getGraphObject("LoadPowerSEAShell", m_loadPowerObjHash, abLoad);
            break;
        case Acoustics::FITKAcousticsAbstractLoad::PowerSEAAcoustic:
            obj = getGraphObject("LoadPowerSEAAcoustic", m_loadPowerObjHash, abLoad);
            break;
        case Acoustics::FITKAcousticsAbstractLoad::PowerFESubsys:
            obj = getGraphObject("LoadPowerFESubsys", m_loadPowerObjHash, abLoad);
            break;
        case Acoustics::FITKAcousticsAbstractLoad::ExcitationForceMoments:
            obj = getGraphObject("LoadExcForMom", m_loadPowerObjHash, abLoad);
            break;
        case Acoustics::FITKAcousticsAbstractLoad::ExcitationMonopole:
            obj = getGraphObject("LoadMonopole", m_loadMonopoleObjHash, abLoad);
            break;
        default:
            break;
        }
        return obj;
    }

    QList<Exchange::FITKAcousticsVTKGraphObject3D*> GraphMarkProvider::getAllLoadGraphObjects(bool autoCreate)
    {
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> graphObjs = {};
        if (m_loadManager == nullptr)return graphObjs;

        QList<Acoustics::FITKAcousticsAbstractLoad*> connectLoad = {};
        connectLoad.append(m_loadManager->getLoadByType(Acoustics::FITKAcousticsAbstractLoad::AcousticsLoadType::ImportNoiseHVAC));
        connectLoad.append(m_loadManager->getLoadByType(Acoustics::FITKAcousticsAbstractLoad::AcousticsLoadType::ConstraintSEABeam));
        connectLoad.append(m_loadManager->getLoadByType(Acoustics::FITKAcousticsAbstractLoad::AcousticsLoadType::ConstraintSEAShell));
        connectLoad.append(m_loadManager->getLoadByType(Acoustics::FITKAcousticsAbstractLoad::AcousticsLoadType::ConstraintSEAAcoustic));
        connectLoad.append(m_loadManager->getLoadByType(Acoustics::FITKAcousticsAbstractLoad::AcousticsLoadType::ConstraintFESubsys));
        connectLoad.append(m_loadManager->getLoadByType(Acoustics::FITKAcousticsAbstractLoad::AcousticsLoadType::PowerSEABeam));
        connectLoad.append(m_loadManager->getLoadByType(Acoustics::FITKAcousticsAbstractLoad::AcousticsLoadType::PowerSEAShell));
        connectLoad.append(m_loadManager->getLoadByType(Acoustics::FITKAcousticsAbstractLoad::AcousticsLoadType::PowerSEAAcoustic));
        connectLoad.append(m_loadManager->getLoadByType(Acoustics::FITKAcousticsAbstractLoad::AcousticsLoadType::PowerFESubsys));
        connectLoad.append(m_loadManager->getLoadByType(Acoustics::FITKAcousticsAbstractLoad::AcousticsLoadType::ExcitationForceMoments));
        connectLoad.append(m_loadManager->getLoadByType(Acoustics::FITKAcousticsAbstractLoad::AcousticsLoadType::ExcitationMonopole));

        for (Acoustics::FITKAcousticsAbstractLoad* loadConn : connectLoad){
            if (loadConn == nullptr) continue;

            // 获取或创建载荷。
            Exchange::FITKAcousticsVTKGraphObject3D* graphObj = getLoadGraphObject(loadConn->getDataObjectID());
            if (graphObj == nullptr)continue;
            if (autoCreate) {
                graphObj->updateById(loadConn->getDataObjectID(), autoCreate);
            }
            graphObjs.append(graphObj);
        }
        return graphObjs;
    }

    Exchange::FITKAcousticsVTKGraphObject3D* GraphMarkProvider::getCurrentGraphObjByDataId(int dataObjId)
    {
        // 查找连接点。
        if (m_SEAJuncPointObjHash.contains(dataObjId))
        {
            return m_SEAJuncPointObjHash[dataObjId];
        }

        // 查找连接线。
        if (m_SEAJuncLinesObjHash.contains(dataObjId))
        {
            return m_SEAJuncLinesObjHash[dataObjId];
        }

        // 查找连接区域。
        if (m_SEAJuncAreasObjHash.contains(dataObjId))
        {
            return m_SEAJuncAreasObjHash[dataObjId];
        }

        // 不查询SEA模型自由边对象。

        return nullptr;
    }

    Exchange::FITKAcousticsVTKGraphObject3D * GraphMarkProvider::getDirectionGraphObj(int& dataObjID)
    {
        Exchange::FITKAcousticsVTKGraphObject3D* graphObj = nullptr;
        if (m_graphToolObjHash.keys().contains(dataObjID)){
            graphObj = m_graphToolObjHash[dataObjID];
            return graphObj;
        }

        graphObj = getGraphObject("GraphTool", "ToolDirection");
        if (graphObj == nullptr) {
            return nullptr;
        }

        m_graphToolId++;
        dataObjID = m_graphToolId;
        m_graphToolObjHash.insert(m_graphToolId, graphObj);
        return graphObj;
    }

    void GraphMarkProvider::deleteToolGraphObj(int dataObjID)
    {
        Exchange::FITKAcousticsVTKGraphObject3D* graphObj = m_graphToolObjHash.take(dataObjID);
        if (graphObj != nullptr) {
            delete graphObj;
            graphObj = nullptr;
        }
    }

    void GraphMarkProvider::setDoubleClickPickable(bool pickable)
    {
        // SEA连接关系。
        setSEAJunctionsPickable(pickable);
        // FE连接关系
        setFEJunctionsPickable(pickable);
        // 混合连接关系
        setHybridJunctionsPickable(pickable);
        // 载荷。
        setLoadsPickable(pickable);
    }

    void GraphMarkProvider::setSEAJunctionsPickable(bool pickable)
    {
        Exchange::FITKAcousticsVTKCommons::ShapePickMode pickMode = pickable ?
            Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickAll :
            Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone;

        // 开启或关闭可拾取状态。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs =
            m_SEAJuncPointObjHash.values() +
            m_SEAJuncLinesObjHash.values() +
            m_SEAJuncAreasObjHash.values();
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs)
        {
            if (!obj)
            {
                continue;
            }

            obj->setPickMode(pickMode);
        }
    }

    void GraphMarkProvider::setFEJunctionsPickable(bool pickable)
    {
        Exchange::FITKAcousticsVTKCommons::ShapePickMode pickMode = pickable ?
            Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickAll :
            Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone;

        // 开启或关闭可拾取状态。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs =
            m_FEJuncPointObjHash.values() +
            m_FEJuncLinesObjHash.values() +
            m_FEJuncAreasObjHash.values();
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs)
        {
            if (!obj)
            {
                continue;
            }

            obj->setPickMode(pickMode);
        }
    }

    void GraphMarkProvider::setHybridJunctionsPickable(bool pickable)
    {
        Exchange::FITKAcousticsVTKCommons::ShapePickMode pickMode = pickable ?
            Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickAll :
            Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone;

        // 开启或关闭可拾取状态。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs =
            m_HybridJuncPointObjHash.values() +
            m_HybridJuncLinesObjHash.values() +
            m_HybridJuncAreasObjHash.values();
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs)
        {
            if (!obj)
            {
                continue;
            }

            obj->setPickMode(pickMode);
        }
    }

    void GraphMarkProvider::setSEAJunctionPointPickable(bool pickable, int dataObjId)
    {
        Exchange::FITKAcousticsVTKCommons::ShapePickMode pickMode = pickable ?
            Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickAll :
            Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone;

        // 开启或关闭可拾取状态。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = m_SEAJuncPointObjHash.values();
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs)
        {
            if (!obj)
            {
                continue;
            }

            if (obj->getDataId() != dataObjId && dataObjId != -1)
            {
                obj->setPickMode(Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone);
            }
            else
            {
                obj->setPickMode(pickMode);
            }
        }
    }

    void GraphMarkProvider::setSEAJunctionLinePickable(bool pickable, int dataObjId)
    {
        Exchange::FITKAcousticsVTKCommons::ShapePickMode pickMode = pickable ?
            Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickAll :
            Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone;

        // 开启或关闭可拾取状态。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = m_SEAJuncLinesObjHash.values();
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs)
        {
            if (!obj)
            {
                continue;
            }

            if (obj->getDataId() != dataObjId && dataObjId != -1)
            {
                obj->setPickMode(Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone);
            }
            else
            {
                obj->setPickMode(pickMode);
            }
        }
    }

    void GraphMarkProvider::setSEAJunctionAreaPickable(bool pickable, int dataObjId)
    {
        Exchange::FITKAcousticsVTKCommons::ShapePickMode pickMode = pickable ?
            Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickAll :
            Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone;

        // 开启或关闭可拾取状态。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = m_SEAJuncAreasObjHash.values();
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs)
        {
            if (!obj)
            {
                continue;
            }

            if (obj->getDataId() != dataObjId && dataObjId != -1)
            {
                obj->setPickMode(Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone);
            }
            else
            {
                obj->setPickMode(pickMode);
            }
        }
    }

    void GraphMarkProvider::setLoadsPickable(bool pickable, int dataObjId)
    {
        Exchange::FITKAcousticsVTKCommons::ShapePickMode pickMode = pickable ?
            Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickAll :
            Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone;

        // 开启或关闭可拾取状态。
        QList<Exchange::FITKAcousticsVTKGraphObject3D*> objs = {};
        objs << m_loadPointForceObjHash.values();
        objs << m_loadPowerObjHash.values();
        objs << m_loadConstraintObjHash.values();
        objs << m_importNoiseHVACHash.values();
        objs << m_loadMonopoleObjHash.values();
        for (Exchange::FITKAcousticsVTKGraphObject3D* obj : objs)
        {
            if (!obj)
            {
                continue;
            }

            if (obj->getDataId() != dataObjId && dataObjId != -1)
            {
                obj->setPickMode(Exchange::FITKAcousticsVTKCommons::ShapePickMode::PickNone);
            }
            else
            {
                obj->setPickMode(pickMode);
            }
        }
    }

    Exchange::FITKAcousticsVTKGraphObjectScalarBars* GraphMarkProvider::getScalarBarsGraphObject()
    {
        if (!m_scalarBarObj)
        {
            m_scalarBarObj = new Exchange::FITKAcousticsVTKGraphObjectScalarBars;
        }

        return m_scalarBarObj;
    }
}   // namespace GraphData